﻿// -----------------------------------------------------------------------
// <copyright file="Player.cs" company="DarkBone">
// DarkBone
// </copyright>
// -----------------------------------------------------------------------

namespace DarkBone.Engine.Collections
{
   using System;
   using System.Collections.Generic;
   using System.Drawing;

   using DarkBone.Engine.SC2;

   /// <summary>
   /// Contains player information
   /// </summary>
   public sealed class Player : IComparable
   {
      /// <summary>
      /// Player colours
      /// </summary>
      private readonly Color[] colors = new Color[]
         {
            Color.White, Color.Red, Color.Blue, Color.Teal, Color.Purple, Color.Yellow, Color.Orange, Color.Green,
            Color.LightPink, Color.Violet, Color.LightGray, Color.DarkGreen, Color.Brown, Color.LightGreen,
            Color.DarkGray, Color.Pink
         };
      
      /// <summary>
      /// Holds SC2,PlayerStruct for comparator
      /// </summary>
      private Memory.PlayerStruct playerStruct;

      /// <summary>
      /// Initializes a new instance of the <see cref="Player"/> class.
      /// </summary>
      /// <param name="playerStruct">The player struct.</param>
      public Player(Memory.PlayerStruct playerStruct)
      {
         this.PlayerStruct = playerStruct;
         this.ArmySize = new List<int>();
      }

      /// <summary>
      /// Gets or sets player units
      /// </summary>
      /// <value>
      /// The units.
      /// </value>
      public List<Unit> Units { get; set; }

      /// <summary>
      /// Gets or sets player units
      /// </summary>
      /// <value>
      /// The unit summary.
      /// </value>
      public IEnumerable<UnitSummary> UnitSummary { get; set; }

      /// <summary>
      /// Gets or sets a value indicating whether this <see cref="Player"/> is enemy.
      /// </summary>
      /// <value>
      ///   <c>true</c> if enemy; otherwise, <c>false</c>.
      /// </value>
      public bool Enemy { get; set; }

      /// <summary>
      /// List of armysize
      /// </summary>
      public List<int> ArmySize { get; set; }

      /// <summary>
      /// Gets or sets PlayerStruct.
      /// </summary>
      /// <value>
      /// The player struct.
      /// </value>
      public Memory.PlayerStruct PlayerStruct
      {
         get
         {
            return this.playerStruct;
         }

         set
         {
            this.playerStruct = value;
         }
      }


      /// <summary>
      /// Gets the color.
      /// </summary>
      public Color Color
      {
         get
         {
            return this.colors[this.playerStruct.ColorIndex];
         }
      }

      /// <summary>
      /// Gets the color.
      /// </summary>
      public Color TeamColor
      {
         get
         {
            return (this.playerStruct.Teamslot >= 10) ? this.colors[0] : this.colors[this.playerStruct.Teamslot + 1];
         }
      }

      /// <summary>
      /// Compares this to other object
      /// </summary>
      /// <param name="obj">The obj.</param>
      /// <returns>
      /// Zero if object are same
      /// </returns>
      /// <exception cref="T:System.ArgumentException">
      /// <paramref name="obj"/> is not the same type as this instance. </exception>
      public int CompareTo(object obj)
      {
         if (obj is Player)
         {
            return this.PlayerStruct.Index.Equals(((Player)obj).PlayerStruct.Index) ? 0 : -1;
         }

         return -1;
      }

      /// <summary>
      /// Overrides Equals
      /// </summary>
      /// <param name="obj">The obj.</param>
      /// <returns>
      /// True if object are same
      /// </returns>
      public override bool Equals(object obj)
      {
         return this.CompareTo(obj) == 0;
      }

      /// <summary>
      /// Checks if object is equal
      /// </summary>
      /// <param name="other">The other.</param>
      /// <returns>
      /// True if equal
      /// </returns>
      public bool Equals(Player other)
      {
         if (ReferenceEquals(null, other))
         {
            return false;
         }

         return ReferenceEquals(this, other) || other.playerStruct.Index.Equals(this.playerStruct.Index);
      }

      /// <summary>
      /// Gets hashcode of playerStruct
      /// </summary>
      /// <returns>
      /// Hash code
      /// </returns>
      public override int GetHashCode()
      {
         return this.playerStruct.GetHashCode();
      }
   }
}
